/*

Summary:
Use to change uppercase letters to lowercase, or change
lowercase letters to uppercase, in a string.

Remark:
For non-const string, modification would apply to it, and
ToUppercase/ToLowercase returns nothing. For const string,
ToUppercase/ToLowercase would return a new string.

Version:
0.0.1

LastUpdatedDate:
2012-08-15

CreatedDate:
2012-08-15

*/


#pragma once
#include <string>



namespace Zaf {
namespace String {
namespace __Internal {

	
template<typename CharType>
struct __ToUpperWrapper {
	static CharType __ToUpper(CharType c);
};

template<>
struct __ToUpperWrapper<char> {
	static char __ToUpper(char c) {
		return (char)::toupper(c);
	}
};

template<>
struct __ToUpperWrapper<wchar_t> {
	static wchar_t __ToUpper(wchar_t c) {
		return (wchar_t)::towupper(c);
	}
};



template<typename CharType>
struct __ToLowerWrapper {
	static CharType __ToLower(CharType c);
};

template<>
struct __ToLowerWrapper<char> {
	static char __ToLower(char c) {
		return (char)::tolower(c);
	}
};

template<>
struct __ToLowerWrapper<wchar_t> {
	static wchar_t __ToLower(wchar_t c) {
		return (wchar_t)::towlower(c);
	}
};


} // __Internal



template<typename CharType>
void ToUppercase(std::basic_string<CharType>& str) {

	for (auto it = str.begin(); it != str.end(); ++it) {
		*it = __Internal::__ToUpperWrapper<CharType>::__ToUpper(*it);
	}
}

template<typename CharType>
std::basic_string<CharType> ToUppercase(const std::basic_string<CharType>& str) {

	std::basic_string<CharType> result(str);
	ToUppercase(result);
	return result;
}



template<typename CharType>
void ToLowercase(std::basic_string<CharType>& str) {

	for (auto it = str.begin(); it != str.end(); ++it) {
		*it = __Internal::__ToLowerWrapper<CharType>::__ToLower(*it);
	}
}

template<typename CharType>
std::basic_string<CharType> ToLowercase(const std::basic_string<CharType>& str) {

	std::basic_string<CharType> result(str);
	ToLowercase(result);
	return result;
}



} // String
} // Zaf